package com.yida.system.config;

import java.math.BigDecimal;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.yida.common.core.constant.CacheConstants;
import com.yida.common.core.enums.DelFlagEnum;
import com.yida.common.core.enums.EnableTypeEnum;
import com.yida.common.core.enums.LimitTimeTypeEnum;
import com.yida.common.redis.service.RedisService;
import com.yida.system.api.domain.SysBlackConfig;
import com.yida.system.api.domain.SysBlackList;
import com.yida.system.api.domain.SysWhiteList;
import com.yida.system.mapper.SysBlackConfigMapper;
import com.yida.system.mapper.SysBlackListMapper;
import com.yida.system.mapper.SysWhiteListMapper;

import cn.hutool.core.date.LocalDateTimeUtil;

/**
 * @Description 黑白名单初始化
 * @Author wws
 * @Date 2023-03-20
 */

@Configuration
// @RequiredArgsConstructor
public class BlackWhiteInitConfig {

    @Autowired
    private RedisService redisService;
    @Autowired
    private SysBlackListMapper sysBlackListMapper;
    @Autowired
    private SysWhiteListMapper sysWhiteListMapper;
    @Autowired
    private SysBlackConfigMapper sysBlackConfigMapper;

    // @Qualifier("redisTemplate")
    // final RedisService redisService;
    //
    // final SysBlackListMapper sysBlackListMapper;
    //
    // final SysWhiteListMapper sysWhiteListMapper;
    //
    // final SysBlackConfigMapper sysBlackConfigMapper;

    @Bean
    void initData() {
        // 查询黑名单配置
        SysBlackConfig blackConfig = getBlackConfig();
        // 查询白名单列表
        List<SysWhiteList> whiteLists = getWhiteLists();
        // 查询黑名单限时列表
        List<SysBlackList> limitBlackLists = getLimitBlackLists();
        // 查询黑名单永久列表
        List<SysBlackList> permanentBlackLists = getPermanentBlackLists();
        // 黑名单配置缓存处理
        // System.out.println("?:" + redisService.hasKey(CacheConstants.BLACK_CONFIG_KEY));
        if (!redisService.hasKey(CacheConstants.BLACK_CONFIG_KEY)) {
            // redisTemplate.opsForValue().set(CacheConstants.BLACK_CONFIG_KEY, JSONUtil.parse(blackConfig));
            redisService.setCacheObject(CacheConstants.BLACK_CONFIG_KEY, blackConfig);
        }
        // 白名单列表缓存处理
        whiteLists.forEach(item -> {
            // if (!redisTemplate.boundSetOps(CacheConstants.WHITE_LIST_KEY).isMember(item.getIpAddress())) {
            Set<String> set = redisService.getCacheSet(CacheConstants.WHITE_LIST_KEY);
            if (!set.contains(item.getIpAddress())) {
                set.add(item.getIpAddress());
                redisService.setCacheSet(CacheConstants.WHITE_LIST_KEY, set);
            }
        });
        // 黑名单限时列表缓存处理
        limitBlackLists.forEach(item -> {
            if (!redisService.hasKey(CacheConstants.BLACK_LIST + CacheConstants.REDIS_SUFFIX + item.getIpAddress())) {
                redisService.setCacheObject(
                    CacheConstants.BLACK_LIST + CacheConstants.REDIS_SUFFIX + item.getIpAddress(), item.getIpAddress(),
                    item.getLimitTime().longValue(), TimeUnit.MINUTES);
            }
        });
        // 黑名单永久列表缓存处理
        permanentBlackLists.forEach(item -> {
            if (!redisService.hasKey(CacheConstants.BLACK_LIST + CacheConstants.REDIS_SUFFIX + item.getIpAddress())) {
                redisService.setCacheObject(
                    CacheConstants.BLACK_LIST + CacheConstants.REDIS_SUFFIX + item.getIpAddress(), item.getIpAddress());
            }
        });

    }

    /**
     * 查询黑名单配置
     * 
     * @return 黑名单配置
     */

    private SysBlackConfig getBlackConfig() {
        SysBlackConfig sysBlackConfig = new SysBlackConfig();
        sysBlackConfig.setDelFlag(DelFlagEnum.NORMAL.getType());
        return sysBlackConfigMapper.selectSysBlackConfig(sysBlackConfig);
    }

    /**
     * 查询状态为开启的白名单信息
     * 
     * @return 白名单集合
     */
    private List<SysWhiteList> getWhiteLists() {
        SysWhiteList SysWhiteList = new SysWhiteList();
        SysWhiteList.setDelFlag(DelFlagEnum.NORMAL.getType());
        SysWhiteList.setStatus(EnableTypeEnum.UNLOCK.getType());
        return sysWhiteListMapper.selectSysWhiteListList(SysWhiteList);
    }

    /**
     * 查询限时黑名单信息
     * 
     * @return 黑名单集合
     */

    private List<SysBlackList> getLimitBlackLists() {
        SysBlackList sysBlackList = new SysBlackList();
        sysBlackList.setDelFlag(DelFlagEnum.NORMAL.getType());
        sysBlackList.setLimitTimeType(LimitTimeTypeEnum.LIMIT.getType());
        return sysBlackListMapper.selectSysBlackListList(sysBlackList).stream()
            // 过滤过期数据
            .filter(item -> LocalDateTimeUtil.now()
                .isBefore(LocalDateTimeUtil.offset(LocalDateTimeUtil.of(item.getCreateTime()),
                    item.getLimitTime().longValue(), ChronoUnit.MINUTES)))
            // 重新计算限制时间
            .map(item -> {
                item.setLimitTime(new BigDecimal(LocalDateTimeUtil.between(LocalDateTimeUtil.now(),
                    LocalDateTimeUtil.offset(LocalDateTimeUtil.of(item.getCreateTime()),
                        item.getLimitTime().longValue(), ChronoUnit.MINUTES))
                    .toMinutes()));
                return item;
            }).collect(Collectors.toList());
    }

    /**
     * 查询永久黑名单信息
     */
    private List<SysBlackList> getPermanentBlackLists() {
        SysBlackList sysBlackList = new SysBlackList();
        sysBlackList.setDelFlag(DelFlagEnum.NORMAL.getType());
        sysBlackList.setLimitTimeType(LimitTimeTypeEnum.PERMANENT.getType());
        return sysBlackListMapper.selectSysBlackListList(sysBlackList);
    }

}
